package com.google.code.lightsomy.output;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.code.lightsomy.errors.ApplicationException;
import com.google.code.lightsomy.http.LightsomyConstants;

/**
 * Abstract template engine renderer.
 * 
 * @author Viktoras Agejevas
 *
 */
public abstract class LightsomyRenderer extends Renderer {

	final private Type type;
	
	final private HttpServletRequest request;
	
	final private HttpServletResponse response;
	
	private String layout;
	

	public abstract void set(String key, Object value);

	public abstract Object get(String key);
	
	protected abstract String process(String page);

	protected LightsomyRenderer(HttpServletRequest request, HttpServletResponse response, Type type) {
		this.type = type;
		this.request = request;
		this.response = response;
	}
	
	@Override
	public String render(String page) {
		set(LightsomyConstants.INCLUDE.getValue(), page);

		if (!"".equals(request.getAttribute(LightsomyConstants.LAYOUT.getValue()))) {
			setLayout((String) request.getAttribute(LightsomyConstants.LAYOUT.getValue()));
		}
		
		if (getLayout() != null) {
			page = getLayout();
		}
		
		return process(page);
	}

	@Override
	public String render() {
		String controller = request.getParameter(LightsomyConstants.CONTROLLER.getValue());
		String action = request.getParameter(LightsomyConstants.ACTION.getValue());
		String page = "/view/" + controller.toLowerCase() + "/" + action + type.getExtension();
		return render(page);
	}
	
	@Override
	public void output(String contents) {
		try {
			response.getWriter().append(contents).flush();
		} catch (IOException e) {
			throw new ApplicationException("Failed to output the page", e);
		}
	}
	
	@Override
	public void setLayout(String page) {
		layout = page;
	}
	
	@Override
	public String getLayout() {
		return layout;
	}
	
	public HttpServletRequest getRequest() {
		return request;
	}

	public HttpServletResponse getResponse() {
		return response;
	}
}
